﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.Text;
using Uplink2PublicService.U2Svc;
using Type = System.Type;

namespace Uplink2.Webservices
{
	[ServiceContract(Name = "Uplink2Service", Namespace = "Uplink2.Webservices.Internal")]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public partial class Uplink2Service
	{
		[OperationContract]
		public bool PersistEntity(Guid sessionId, EntityBase b, int numRecursionLevels, bool doInsert)
		{
			return new U2SvcClient().PersistEntity(sessionId, b, numRecursionLevels, doInsert);
		}

		[OperationContract]
		public EntityBase ObtainEntity(Guid sessionId, Guid entityId)
		{
			return new U2SvcClient().ObtainEntity(sessionId, entityId);
		}

		[OperationContract]
		public List<EntityBase> ObtainEntityByType(Guid sessionId, Entities t)
		{
			return new U2SvcClient().ObtainEntitiesByType(sessionId, t);
		}

		[OperationContract]
		public bool DeleteEntity(Guid sessionId, List<EntityBase> b)
		{
			return new U2SvcClient().DeleteEntity(sessionId, b);
		}

		[OperationContract]
		public List<string> GetAvailableProgramMethods(Guid sessionId)
		{
			return new U2SvcClient().GetAvailableProgramMethods(sessionId);
		}

		#region Login/Logout/Registration
		[OperationContract]
		public ClientConfiguration Login(string login, string password)
		{
			return new U2SvcClient().Login(login, password);
		}

		[OperationContract]
		public bool Logout(Guid sessionId, string login, string password)
		{
			return new U2SvcClient().Logout(sessionId, login, password);
		}

		[OperationContract]
		public bool RegisterAccount(string login, string password, string agentName, Guid corporationId)
		{
			return new U2SvcClient().RegisterAccount(login, password, agentName, corporationId);
		}
		#endregion

		[OperationContract]
		public List<SystemFile> GetFilesInDirectory(Guid sessionId, Guid systemId)
		{
			return new U2SvcClient().GetFilesInDirectory(sessionId, systemId);
		}

		[OperationContract]
		public SystemDirectory GetSystemRoot(Guid sessionId, Guid systemId)
		{
			return new U2SvcClient().GetSystemRoot(sessionId, systemId);
		}

		[OperationContract]
		public int GetMyTotalMemory(Guid sessionId)
		{
			return new U2SvcClient().GetMyTotalMemory(sessionId);
		}

		#region Generic NetworkAddress helper functions
		[OperationContract]
		public List<NetworkAddress> GetAvailableNetworkAddresses(Guid sessionId)
		{
			return new U2SvcClient().GetAvailableNetworkAddresses(sessionId);
		}

		[OperationContract]
		public bool GenerateRandomAddresses(Guid sessionId, int amount)
		{
			return new U2SvcClient().GenerateRandomAddresses(sessionId, amount);
		}
		#endregion

		[OperationContract]
		public List<ComputerSystem> GetMyKnownComputerSystems(Guid sessionId)
		{
			return new U2SvcClient().GetMyKnownComputerSystems(sessionId);
		}

		#region Program handling
		[OperationContract]
		public bool ExecuteProgram(Guid sessionId, Guid programId, List<object> parameters)
		{
			return new U2SvcClient().ExecuteProgram(sessionId, programId, parameters);
		}
		[OperationContract]
		public List<Program> GetMyPrograms(Guid sessionId)
		{
			return new U2SvcClient().GetMyPrograms(sessionId);
		}

		#endregion

		#region Connection handling
		[OperationContract]
		public Guid? Connect_ConnectToSystem(Guid sessionId, List<Guid> connectionPathIds)
		{
			return new U2SvcClient().Connect_ConnectToSystem(sessionId, connectionPathIds);
		}

		[OperationContract]
		public List<ComputerSystemFeature> Connect_GetConnectedHostFeatures(Guid sessionId, Guid connectionId)
		{
			return new U2SvcClient().Connect_GetConnectedHostFeatures(sessionId, connectionId);
		}

		[OperationContract]
		public bool Connect_TryAccess(Guid sessionId, Guid connectionId, Guid securitySystemId, List<object> methodParameters)
		{
			return new U2SvcClient().Connect_TryAccess(sessionId, connectionId, securitySystemId, methodParameters);
		}

		[OperationContract]
		public bool Connect_LoginToSystemAllowed(Guid sessionId, Guid connectionId)
		{
			return new U2SvcClient().Connect_LoginToSystemAllowed(sessionId, connectionId);
		}

		[OperationContract]
		public bool Connect_LoginToSystem(Guid sessionId, Guid connectionId)
		{
			return new U2SvcClient().Connect_LoginToSystem(sessionId, connectionId);
		}

		[OperationContract]
		public bool Connect_DisconnectFromSystem(Guid sessionId, Guid connectionId)
		{
			return new U2SvcClient().Connect_DisconnectFromSystem(sessionId, connectionId);
		}
		#endregion

		#region ComputerSystem handling
		[OperationContract]
		public List<ComputerSystemLog> GetSystemLogs(Guid sessionId, Guid systemId)
		{
			return new U2SvcClient().GetSystemLogs(sessionId, systemId);
		}

		#endregion
	}

	public class SessionValidator : UserNamePasswordValidator
	{
		public override void Validate(string userName, string password)
		{
			if (string.IsNullOrEmpty(userName) || string.IsNullOrWhiteSpace(userName))
				throw new SecurityTokenException("Session ID empty.");
			
			Guid sessionId;
			
			if(!Guid.TryParse(userName, out sessionId))
				throw new SecurityTokenException("SessionID not valid.");

			if (!new U2SvcClient().VerifySession(sessionId))
				throw new SecurityTokenException("Session invalid.");
		}
	}
}
